#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <stdio.h>
#include <stdlib.h>

// 窗口状态枚举
typedef enum {
    NORMAL,
    MAXIMIZED,
    MINIMIZED
} WindowState;

// 窗口信息结构体
typedef struct {
    Display *display;
    Window window;
    int screen;
    WindowState state;
    unsigned int width, height;
    int x, y;
} WindowInfo;

// 初始化窗口
WindowInfo* init_window(const char *title, int width, int height) {
    WindowInfo *winfo = (WindowInfo*)malloc(sizeof(WindowInfo));
    if (!winfo) return NULL;
    
    // 连接到X服务器
    winfo->display = XOpenDisplay(NULL);
    if (!winfo->display) {
        fprintf(stderr, "无法连接到X服务器\n");
        free(winfo);
        return NULL;
    }
    
    // 获取屏幕信息
    winfo->screen = DefaultScreen(winfo->display);
    winfo->width = width;
    winfo->height = height;
    
    // 创建窗口
    winfo->window = XCreateSimpleWindow(
        winfo->display,
        RootWindow(winfo->display, winfo->screen),
        0, 0, width, height,
        1,  // 边框宽度
        BlackPixel(winfo->display, winfo->screen),  // 边框颜色
        WhitePixel(winfo->display, winfo->screen)   // 背景颜色
    );
    
    // 设置窗口标题
    XStoreName(winfo->display, winfo->window, title);
    
    // 选择要接收的事件
    XSelectInput(winfo->display, winfo->window, 
        ExposureMask | KeyPressMask | StructureNotifyMask);
    
    // 映射窗口（显示）
    XMapWindow(winfo->display, winfo->window);
    
    // 初始化窗口状态
    winfo->state = NORMAL;
    
    return winfo;
}

// 窗口最大化
void maximize_window(WindowInfo *winfo) {
    if (winfo->state == MAXIMIZED) return;
    
    // 保存当前窗口位置和大小
    XWindowAttributes attrs;
    XGetWindowAttributes(winfo->display, winfo->window, &attrs);
    winfo->x = attrs.x;
    winfo->y = attrs.y;
    winfo->width = attrs.width;
    winfo->height = attrs.height;
    
    // 获取屏幕大小
    int screen_width = DisplayWidth(winfo->display, winfo->screen);
    int screen_height = DisplayHeight(winfo->display, winfo->screen);
    
    // 调整窗口大小为屏幕大小
    XMoveResizeWindow(winfo->display, winfo->window, 0, 0, 
                     screen_width, screen_height);
    
    winfo->state = MAXIMIZED;
}

// 窗口最小化
void minimize_window(WindowInfo *winfo) {
    if (winfo->state == MINIMIZED) return;
    
    // 保存当前窗口位置和大小
    XWindowAttributes attrs;
    XGetWindowAttributes(winfo->display, winfo->window, &attrs);
    winfo->x = attrs.x;
    winfo->y = attrs.y;
    winfo->width = attrs.width;
    winfo->height = attrs.height;
    
    // 图标化窗口（最小化）
    XIconifyWindow(winfo->display, winfo->window, winfo->screen);
    
    winfo->state = MINIMIZED;
}

// 窗口恢复正常大小
void restore_window(WindowInfo *winfo) {
    if (winfo->state == NORMAL) return;
    
    // 恢复窗口大小
    XMoveResizeWindow(winfo->display, winfo->window, 
                     winfo->x, winfo->y, 
                     winfo->width, winfo->height);
    
    // 如果窗口被最小化，先恢复显示
    if (winfo->state == MINIMIZED) {
        XMapWindow(winfo->display, winfo->window);
    }
    
    winfo->state = NORMAL;
}

// 清理资源
void cleanup_window(WindowInfo *winfo) {
    if (!winfo) return;
    
    XDestroyWindow(winfo->display, winfo->window);
    XCloseDisplay(winfo->display);
    free(winfo);
}

int main() {
    WindowInfo *winfo = init_window("X11 Window Manager", 640, 480);
    if (!winfo) return 1;
    
    printf("窗口已创建。\n");
    printf("快捷键：\n");
    printf("  m - 最大化/恢复窗口\n");
    printf("  n - 最小化窗口\n");
    printf("  q - 退出程序\n");
    
    XEvent event;
    Bool running = True;
    
    while (running) {
        // 等待事件
        XNextEvent(winfo->display, &event);
        
        switch (event.type) {
            case Expose:
                // 窗口需要重绘
                if (event.xexpose.count == 0) {
                    // 在这里绘制窗口内容
                    // 例如：XFillRectangle(winfo->display, winfo->window, 
                    //                DefaultGC(winfo->display, winfo->screen), 
                    //                10, 10, 100, 100);
                }
                break;
                
            case KeyPress:
                // 处理键盘事件
                {
                    KeySym key = XLookupKeysym(&event.xkey, 0);
                    switch (key) {
                        case XK_m:  // 'm' 键
                            if (winfo->state == MAXIMIZED) {
                                restore_window(winfo);
                                printf("窗口已恢复正常大小\n");
                            } else {
                                maximize_window(winfo);
                                printf("窗口已最大化\n");
                            }
                            break;
                            
                        case XK_n:  // 'n' 键
                            minimize_window(winfo);
                            printf("窗口已最小化\n");
                            break;
                            
                        case XK_q:  // 'q' 键
                            running = False;
                            break;
                    }
                }
                break;
                
            case ConfigureNotify:
                // 窗口大小或位置改变
                winfo->width = event.xconfigure.width;
                winfo->height = event.xconfigure.height;
                winfo->x = event.xconfigure.x;
                winfo->y = event.xconfigure.y;
                break;
        }
    }
    
    cleanup_window(winfo);
    return 0;
}

